
#include"glheader.h"
#include "vtexture.h"

#include <stdio.h>

VTexture::VTexture (void * im, int w, int h, int format, int type):
  image(im), height(h), width(w), auto_coord(false), func(GL_DECAL)
{
	glPushAttrib(GL_TEXTURE_BIT);
	white[0] = 1.0f;
	white[1] = 1.0f;
	white[2] = 1.0f;
	white[3] = 1.0f;
	if(h == 0)
		dimension = GL_TEXTURE_1D;
	else
		dimension = GL_TEXTURE_2D;
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, &texname);
	glBindTexture(dimension, texname);
	glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_REPEAT);
	if(dimension == GL_TEXTURE_2D){
		glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexImage2D(GL_TEXTURE_2D, 0, format, width,
                height, 0, format, type, image);
	}
	else
		glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, width, 0,
                GL_RGBA, GL_UNSIGNED_BYTE, image);
	glPopAttrib();
}

void VTexture::SetFilter( int mag, int min){
	glPushAttrib(GL_TEXTURE_BIT);
	glBindTexture(dimension, texname);
	glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, mag);
	glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, min);	
	glPopAttrib();
}

void VTexture::SetRepMode(int var, int rmode){
	glPushAttrib(GL_TEXTURE_BIT);
	glBindTexture(dimension, texname);
	if(var == GL_S){
		glTexParameteri(dimension, GL_TEXTURE_WRAP_S, rmode);
	}
	else if(var == GL_T){
		glTexParameteri(dimension, GL_TEXTURE_WRAP_T, rmode);
	}
	glPopAttrib();
}

void VTexture::SetFunction( int f ){
	func = f;
}

void VTexture::SetAutoCoord( int var, int type, float * plane){
	if (var == GL_S){
		s_auto_coord_type = type;
		s_plane[0] = plane[0];
		s_plane[1] = plane[1];
		s_plane[2] = plane[2];
		s_plane[3] = plane[3];
	}
	else if (var == GL_T){
		t_auto_coord_type = type;
		t_plane[0] = plane[0];
		t_plane[1] = plane[1];
		t_plane[2] = plane[2];
		t_plane[3] = plane[3];
	}
}

void VTexture::ActiveAutoCoord(bool active){
	auto_coord = active;
}

void VTexture::Load(){
	glPushAttrib(GL_TEXTURE_BIT);
	glBindTexture(dimension, texname);
	if(auto_coord){
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, s_auto_coord_type);
		if (s_auto_coord_type == GL_OBJECT_LINEAR){
			printf("GL_OBJECT_PLANE\n");
			glTexGenfv(GL_S, GL_OBJECT_PLANE, s_plane);
		}
		else if (s_auto_coord_type == GL_EYE_LINEAR){
			printf("GL_EYE_PLANE\n");
			glPushMatrix();
			glLoadIdentity();
			glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
			glPopMatrix();
		}
		glEnable(GL_TEXTURE_GEN_S);
		if(dimension == GL_TEXTURE_2D){
			printf("2D\n");
			glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, t_auto_coord_type);
			if (t_auto_coord_type == GL_OBJECT_LINEAR){
				glTexGenfv(GL_T, GL_OBJECT_PLANE, t_plane);
			}
			else if (t_auto_coord_type == GL_EYE_LINEAR){
				glPushMatrix();
				glLoadIdentity();
				glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
				glPopMatrix();
			}
			glEnable(GL_TEXTURE_GEN_T);
		}
	}
	//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, func);
	glEnable(dimension);
	if(func == GL_MODULATE){
		glPushAttrib(GL_LIGHTING_BIT);
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,   white);
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,   white);
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  white);
		glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS,  50.0f);
	}
}

void VTexture::Unload(){
	if(func == GL_MODULATE)
		glPopAttrib();
	glPopAttrib();
}

		
